﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace ScFramework.Core
{
    /// <summary>
    /// 所有流程的基类。
    /// </summary>
    public class ProcedureBase
    {
        private Main _main;
        /// <summary>
        /// 获取静态组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        protected  T GetSystemModule<T>()where T:SystemModule=>_main.Get<T>();
        
        protected List<SubmoduleBase> Submodules = new List<SubmoduleBase>();


        public T GetSubmodule<T>()where T : SubmoduleBase
        {
            return Submodules.Find(s => s.GetType() == typeof(T))as T;
        }

        public void Close(SubmoduleBase sub)
        {
            var ss = Submodules.Find(s => s == sub);
            ss.OnDestroy();
            Submodules.Remove(ss);
        }
        public void AddSubmodule(string submodule, object initArgs = null)
        {
         //   try
            {
             var type= GetSystemModule<Data>().Table.GetString("SubmoduleSetting", submodule, "SubmoduleType");

                var str = GetSystemModule<Data>().Table.GetString("SubmoduleSetting", submodule, "InitArgs");
                object args = initArgs;
                
                if (string.IsNullOrEmpty(str) == false&&initArgs==null)
                {
                    args = str;
                }

                //     var sub = Activator.CreateInstance(Type.GetType(submodule)) as SubmoduleBase;
                AddSubmodule(GetSystemModule<TypeManager>().CreatInstanceByShortName<SubmoduleBase>(type), new List<string>(GetSystemModule<Data>().Table.GetStrings("SubmoduleSetting", submodule, "LogicModuleList")), args);
            }
          /*  catch(Exception e)
            {
                Debug.LogError($"{submodule}参数错误\n" + e);
            }*/

        
        }

        protected void AddSubmodule(SubmoduleBase submodule,List<string>moduleList=null,object initArgs=null)
        {
            if (moduleList != null)
            {
                moduleList.RemoveAll(s => String.IsNullOrEmpty(s));
            }
            Submodules.Add(submodule);
            submodule.InitModules(_main,moduleList,initArgs);
        }
        

        public void Init(object args)
        {
            _main = args as Main;
            OnInit();
        }
        /// <summary>
        ///进入该流程。
        /// </summary>
        public void Enter(List<string>submoduleList,object args)
        {
            if (submoduleList != null)
            {
                foreach (var sub in submoduleList)
                {
                    AddSubmodule(sub);
                }
            }

            OnEnter(args);
        }

        /// <summary>
        ///更新该流程。
        /// </summary>
        public void Update(float elapseSeconds)
        {
            foreach (var m in Submodules)
            {
                if (m.Enable)
                {
                    m.Update();
                }
            }
            OnUpdate(elapseSeconds);
        }

        /// <summary>
        ///当进入该流程时执行。
        /// </summary>
        public void FixedUpdate(float elapseSeconds)
        {
            foreach (var m in Submodules)
            {
                if (m.Enable)
                {
                    m.FixedUpdate();
                }
            }
            OnFixedUpdate(elapseSeconds);
        }

        public virtual void LateFixedUpdate()
        {
            foreach(var m in Submodules)
            {
                m.LateFixedUpdate();
            }
        }
        /// <summary>
        ///当离开该流程时执行。
        /// </summary>
        public void Leave()
        {
            foreach (var m in Submodules)
            {
                m.OnDestroy();
            }
            Submodules.Clear();
            OnLeave();
        }
        public virtual float EnterAnimationTime
        {
            get
            {
                return 0;
            }
        }
        public virtual float LeaveAnimationTime
        {
            get
            {
                return 0;
            }
        }
        /// <summary>
        /// 流程离开之前执行的操作/过场动画
        /// </summary>
        public virtual void LeaveAnimation()
        {
        }
        public virtual void EnterAnimation()
        {
        }

        /// <summary>
        /// 程序退出时执行，在程序退出时会完成所有流程初始化。
        /// </summary>
        public void Destroy()
        {
            OnDestroy();
        }

        /// <summary>
        /// 程序初始化时执行，在打开程序时会完成所有流程初始化。
        /// </summary>
        protected virtual void OnInit()
        {
        }

        /// <summary>
        ///当进入该流程时执行。
        /// </summary>
        protected virtual void OnEnter(object args)
        {
            EnterAnimation();
        }

        /// <summary>
        /// 每次更新时执行。
        /// </summary>
        /// <param name="elapseSeconds">流逝时间，以秒为单位。</param>
        protected virtual void OnUpdate(float elapseSeconds)
        {
        }

        /// <summary>
        /// 每次物理更新时执行。
        /// </summary>
        /// <param name="elapseSeconds">流逝时间，以秒为单位。</param>
        protected virtual void OnFixedUpdate(float elapseSeconds)
        {
        }

        /// <summary>
        /// 每次离开这个流程时执行。
        /// </summary>
        protected virtual void OnLeave()
        {
            _main.DoRemove(this);
            //GetSystemModule<MessageManager>().RemoveAbout(this);
        }

        /// <summary>
        /// 程序退出时执行，在程序退出时会完成所有流程初始化。
        /// </summary>
        protected virtual void OnDestroy()
        {
        }

    }
}